package com.dlc.felear.xiaoensale.deviceControlSf;

import android.os.Handler;
import android.os.Message;
import android.text.TextUtils;
import android.util.Log;

import com.dlc.felear.xiaoensale.constant.SfErrorInfo;
import com.dlc.felear.xiaoensale.constant.SfRegAdd;
import com.dlc.felear.xiaoensale.factory.CmdSfList;

import java.util.HashMap;
import java.util.Map;

public class HcSfControlUtil implements Handler.Callback{
    private static final String TAG = "HcSfControlUtil";
    private static final int MSG_DELAY = 1254;
    private static final int DELAY_RUN = 0x3689;
    private int addr;
    private HcSfControl hcSfControl;
    private Map<Integer, Long> resultInfos;
    private int currentCmd = -1;
    private SfResultCallback callback;
    private int flag = 0;
    private boolean runFlag = false;
    private String errorMsg = "";
    private Handler handler;
    private int erorFlag = 0;
    private String tisp = "到达电机限位，不能再向这个方向转动！";
    private int[] positions;
    private String driverType;

    public HcSfControlUtil(int addr, HcSfControl hcSfControl, SfResultCallback callback, int[] position2s,String driverType) {
        this.driverType = driverType;
        this.positions = position2s;
        this.addr = addr;
        this.callback = callback;
        this.hcSfControl = hcSfControl;
        resultInfos = new HashMap<>();
        handler = new Handler(this);
        log("HcSfControlUtil addr="+addr);
    }

    public void loop() {
        startTimer1Sce();
        if (flag % 2 == 0) {
            sendCmd(CmdSfList.sfReadCurrentP(addr));
        }
        if (flag % 10 == 0) {
            sendCmd(CmdSfList.queryfWarn(addr));
        }
        flag++;
        if (flag >= Integer.MAX_VALUE) {
            flag = 0;
        }
    }

    private void startTimer1Sce() {
//        log("startTimer1Sce runFlag="+runFlag+" addr="+addr);
        if (runFlag) {
            sendCmd(CmdSfList.sfStartRun(addr));
        }
    }

    public void recieveData(byte[] data) {
//        log("recieve=" + HexUtil.bytes2HexString(data));
        switch (data[1]) {
            case (byte) 0x03:
                handler03Msg(data);
                break;
            case (byte) 0x06:
                break;
            case (byte) 0x83:
            case (byte) 0x86:
            case (byte) 0x90:
                handler03Msg(data);
                break;
        }
    }

    /**
     * flag 0 正转 1 反转
     *
     * @param flag
     */
    public void singgleStepRun(int flag) {
        runFlag = false;
        int p = getPosition();
        log("当前位置:" + p + " flag=" + flag);

//        if(p>20000||p<-120000){
//            showToastMsg(tisp);
//            return;
//        }
        if (flag == 1) {
            log("点动正转");
            hcSfControl.resetMapValue(CmdSfList.sfRunZz(addr), addr);
        } else {
            log("点动反转");
            hcSfControl.resetMapValue(CmdSfList.sfRunFz(addr), addr);
        }
    }

    /**
     * 设置每一段的位置
     *
     * @param num
     * @param puls
     */
    public void setPlus(int num, int puls) {
        log("段号:" + num + " 脉冲:" + puls);
    }

    public void runExecute(boolean run) {
        log("runExecute run=" + run);
        runFlag = run;
    }


    public void resetYd() {
        log("设置原点");
        sendCmd(CmdSfList.sfSetYd(addr));
    }

    public void resetBmq() {
        log("重置编码器");
        sendCmd(CmdSfList.sfWriteRegister(addr, 0x1406, 0x07));
    }

    /**
     * 运行到指定位置
     *
     * @param num
     */
    public void runDesignatedSpot(int num) {
        log("运行到:" + num + "段");
        runFlag = false;
//        lastIndex = num;
        handler.sendEmptyMessageDelayed(DELAY_RUN, 1000);
        hcSfControl.resetMapValue(CmdSfList.sfRunPosition(addr, num), addr);
    }


    private void handler03Msg(byte[] data) {
        try {
            long temp = 0;
            if (data[2] == 4) {
                temp = converValueTo32(data[5], data[6], data[3], data[4]);
//                log("当前位置:"+temp);
                resultInfos.put(SfRegAdd.R_P_REG, temp);
            } else {
                temp = converValueTo16(data[3], data[4]);
                if (currentCmd == SfRegAdd.R_WARN_REG) {
                    saveResult(currentCmd, temp);
                }
            }
            checkRundone();
        } catch (Exception e) {
            log(e.getMessage());
        }
    }

    private void saveResult(int key, long value) {
        resultInfos.put(key, value);
    }

    private void checkRundone() {
        try {
            int p = getPosition();
            erorFlag = (int) getMapValue(SfRegAdd.R_WARN_REG) >> 2 & 0x01;
            for (int i = 0; i < positions.length; i++) {
                if (Math.abs(positions[i] - p) < 120) {
                    int p1 = i + 1;
                    if (callback != null) {
                        callback.callback(addr, erorFlag, p1, p);
                    }
                    break;
                }
            }
        }catch (Exception e){
            log(e.getMessage());
        }
    }

    private long getMapValue(int key) {
        if (resultInfos.containsKey(key)) {
            return resultInfos.get(key);
        }
        return -1;
    }

    private String handerErrCode(int name, int code) {
        String temp = "";
        if (name == SfRegAdd.R_WARN_REG) {
            temp = SfErrorInfo.getErrorMsg(code);
        }
        return temp;
    }

    private void log(String msg) {
        if(!TextUtils.isEmpty(msg)){
            Log.e(TAG, msg);
        }
    }

    public String getSfErrMsg() {
        if (erorFlag == 1) {
            errorMsg = "电机驱动器有故障，请清除故障";
        } else {
            errorMsg = "";
        }
        return errorMsg;
    }

    public void resetSf() {
        sendCmd(CmdSfList.sfClearWarn(addr));
    }


    public void sendCmd(byte[] data) {
        if (data[1] == 0x03) {
            currentCmd = converValueTo16(data[2], data[3]);
        }
        hcSfControl.sendCmdToQueue(data);
    }

    @Override
    public boolean handleMessage(Message message) {
        if (DELAY_RUN == message.what) {
            log("DELAY_RUN runFlag=" + runFlag + " position:" + getPosition());
            runFlag = true;
        } else if (MSG_DELAY == message.what) {
            callback.callback(addr, (int) message.arg2, message.arg1, getPosition());
            runFlag = false;
            log("运行完成 position:" + message.arg1);
        }
        return false;
    }

    public interface SfResultCallback {
        void callback(int addr, int errorCode, int position, int plus);
    }

    /**
     * 拼接数据
     *
     * @param a
     * @param b
     * @param c
     * @param d
     * @return
     */
    private int converValueTo32(int a, int b, int c, int d) {
        a = 0xFFFFFF | (a << 24);
        b = 0xFF00FFFF | (b << 16);
        c = 0xFFFF00FF | (c << 8);
        d = 0xFFFFFF00 | d;
        return a & b & c & d;
    }

    /**
     * 拼接数据
     *
     * @param c
     * @param d
     * @return
     */
    private int converValueTo16(int c, int d) {
        c = 0x00FF | (c << 8);
        d = 0xFF00 | d;
        return c & d;
    }

    public int getPosition() {
        return (int) getMapValue(SfRegAdd.R_P_REG);
    }

    /**
     * 屏幕显示信息
     *
     * @param msg
     */
    public void showToastMsg(String msg) {
        hcSfControl.showToastMsg(msg);
    }
}
